﻿from google.appengine.ext import db
import datetime
import hashlib,urllib
from google.appengine.api import users
from app.functions.funcs import render,split_tags,formate_time,gen_duration
from google.appengine.api import memcache

def transaction(method):
	def decorate(*args, **kwds):
		return db.run_in_transaction(method, *args, **kwds)
	return decorate

class Post(db.Model):
	title = db.StringProperty()
	content = db.TextProperty()
	post_on = db.DateTimeProperty(auto_now_add=True)
	edit_on = db.DateTimeProperty(auto_now=True)
	author = db.UserProperty()

class SiteConfig(db.Model):
	name = db.StringProperty()
	summary = db.StringProperty()
	manager = db.ListProperty(users.User)
	language = db.StringProperty()

class Players(db.Model):
	player_name = db.StringProperty(required=True)
	player_race = db.StringProperty(required=False)
	player_guild = db.StringProperty(required=False)
	player_sex = db.StringProperty(required=False)
	player_class = db.StringProperty(required=False)
	player_level = db.StringProperty(required=False)

	def player_put(self,adjust=0):
		self.put()
		playerscore = PlayerScore(player=self.key(),adjust=adjust)
		playerscore.put()
		setScoreCache()

	def player_edit(self,adjust=0):
		playerscore = PlayerScore.all().filter('player =',self.key())
		playerscore = playerscore[0]
		playerscore.adjust = adjust
		playerscore.put()
		self.put()
		setScoreCache()

	def player_del(self):
		playerscore = PlayerScore.all().filter('player =',self.key())
		playerscore = playerscore[0]
		playerscore.delete()
		self.delete()
		setScoreCache()

	def get_gender_code(self):
		if self.player_sex == "3":
			return "1"
		elif self.player_sex == "2":
			return "0"

	def get_class_color(self):

		return color_str

	def get_cn_class(self):
		if self.player_class == "WARLOCK":
			cn_class_str = "术士"
		elif self.player_class == "PRIEST":
			cn_class_str = "牧师"
		elif self.player_class == "WARRIOR":
			cn_class_str = "战士"
		elif self.player_class == "SHAMAN":
			cn_class_str = "萨满祭司"
		elif self.player_class == "ROGUE":
			cn_class_str = "潜行者"
		elif self.player_class == "PALADIN":
			cn_class_str = "圣骑士"
		elif self.player_class == "MAGE":
			cn_class_str = "法师"
		elif self.player_class == "HUNTER":
			cn_class_str = "猎人"
		elif self.player_class == "DRUID":
			cn_class_str = "德鲁伊"
		elif self.player_class == "DEATHKNIGHT":
			cn_class_str = "死亡骑士"
		else:
			cn_class_str = "未知职业"
		return cn_class_str
	
	def get_cn_race(self):
		if self.player_race == "Human":
			cn_race_str = "人类"
		elif self.player_race == "Gnome":
			cn_race_str = "侏儒"
		elif self.player_race == "Draenei":
			cn_race_str = "德莱尼人"
		elif self.player_race == "NightElf":
			cn_race_str = "暗夜精灵"
		elif self.player_race == "Dwarf":
			cn_race_str = "矮人"
		elif self.player_race == "Orc":
			cn_race_str = "兽人"
		elif self.player_race == "Undead":
			cn_race_str = "亡灵"
		elif self.player_race == "Troll":
			cn_race_str = "巨魔"
		elif self.player_race == "Tauren":
			cn_race_str = "牛头人"
		elif self.player_race == "BloodElf":
			cn_race_str = "血精灵"
		else:
			cn_race_str = "unknow"
		return cn_race_str

class Guild(db.Model):
	name = db.StringProperty()
	detail = db.StringProperty()
	president =db.ReferenceProperty(Players)

class Raid(db.Model):
	name = db.StringProperty()
	guild = db.ReferenceProperty(Guild)
	members = db.ListProperty(db.Key)

class EventData(db.Model):
	title = db.StringProperty(required=True)
	summary = db.StringProperty(multiline=True)
	content = db.TextProperty()
	author = db.UserProperty()
	post_on = db.DateTimeProperty(auto_now_add=True)
	edit_on = db.DateTimeProperty(auto_now=True)
	start = db.DateTimeProperty()
	end = db.DateTimeProperty()
	members = db.ListProperty(db.Key)
	raid = db.ReferenceProperty(Raid)

	def event_members_num(self):
		return len(self.members)

	def get_absolute_url(self):
		return '%s' %self.key().id()

	def get_duration_h(self):
		h = gen_duration(self.end,self.start)
		return h[0]

	def get_duration_m(self):
		m = gen_duration(self.end,self.start)
		return m[1]

	def update_members(self,oldmembers):
		for player in oldmembers:
			playerscore = PlayerScore.all().filter('player =', player)
			playerscore = playerscore[0]
			playerscore.attend = playerscore.attend - 1
			playerscore.put()
		
		for player in self.members:
			playerscore = PlayerScore.all().filter('player =', player)
			playerscore = playerscore[0]
			playerscore.attend = playerscore.attend + 1
			playerscore.put()
		self.put()
		setScoreCache()

	def event_put(self):
		for player in self.members:
			playerscore = PlayerScore.all().filter('player =', player)
			playerscore = playerscore[0]
			playerscore.attend = playerscore.attend + 1
			playerscore.put()
		self.put()
		setScoreCache()

	def event_del(self):
		actions = ActionInEvent.all().filter('event =',self.key())
		for action in actions:
			action.action_del()

		punishments = PunishmentInEvent.all().filter('event =',self.key())
		for punishment in punishments:
			punishment.action_del()

		rewards = RewardInEvent.all().filter('event =',self.key())
		for reward in rewards:
			reward.action_del()

		gears = GearData.all().filter('event =',self.key())
		for gear in gears:
			gear.gear_del()

		for player in self.members:
			playerscore = PlayerScore.all().filter('player =', player)
			playerscore = playerscore[0]
			playerscore.attend = playerscore.attend - 1
			playerscore.put()

		self.delete()
		setScoreCache()


class GearData(db.Model):
	event = db.ReferenceProperty(EventData)
	gear_name = db.StringProperty()
	gear_id = db.StringProperty()
	gear_color = db.StringProperty()
	gear_icon = db.StringProperty()
	gear_count = db.IntegerProperty()
	gear_player = db.ReferenceProperty(Players)
	gear_costs = db.IntegerProperty()

	def gear_put(self):
		player_score = PlayerScore.all().filter('player =',self.gear_player)
		player_score = player_score[0]
		player_score.cost = player_score.cost + self.gear_costs
		player_score.put()
		self.put()
		setScoreCache()

	def gear_edit(self,oldcost,oldowner):
		playerscore = PlayerScore.all().filter('player =', oldowner)
		playerscore = playerscore[0]
		playerscore.cost = playerscore.cost - oldcost
		playerscore.put()
		playerscore = PlayerScore.all().filter('player =', self.gear_player)
		playerscore = playerscore[0]
		playerscore.cost = playerscore.cost + self.gear_costs
		playerscore.put()
		self.put()
		setScoreCache()

	def gear_del(self):
		player_score = PlayerScore.all().filter('player =',self.gear_player)
		player_score = player_score[0]
		player_score.cost = player_score.cost - self.gear_costs
		player_score.put()
		self.delete()
		setScoreCache()

class ActionInEvent(db.Model):
	title = db.StringProperty()
	summary = db.StringProperty(multiline=True)
	event = db.ReferenceProperty(EventData)
	players = db.ListProperty(db.Key)
	score = db.IntegerProperty()

	def action_edit(self,oldlist,oldscore):
		for player in oldlist:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.earn = player_score.earn - oldscore
			player_score.put()
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.earn = player_score.earn + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_put(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.earn = player_score.earn + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_del(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.earn = player_score.earn - self.score
			player_score.put()
		self.delete()
		setScoreCache()

	def get_players(self):
		return Players.get(self.players)

	def get_players_num(self):
		return len(self.players)

class PunishmentInEvent(ActionInEvent):

	def action_edit(self,oldlist,oldscore):
		for player in oldlist:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.punishment = player_score.punishment - oldscore
			player_score.put()
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.punishment = player_score.punishment + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_put(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.punishment = player_score.punishment + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_del(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.punishment = player_score.punishment - self.score
			player_score.put()
		self.delete()
		setScoreCache()

	def get_players(self):
		return Players.get(self.players)

	def get_players_num(self):
		return len(self.players)

class RewardInEvent(ActionInEvent):

	def action_edit(self,oldlist,oldscore):
		for player in oldlist:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.reward = player_score.reward - oldscore
			player_score.put()
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.reward = player_score.reward + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_put(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.reward = player_score.reward + self.score
			player_score.put()
		self.put()
		setScoreCache()

	def action_del(self):
		for player in self.players:
			player_score = PlayerScore.all().filter('player =',player)
			player_score = player_score[0]
			player_score.reward = player_score.reward - self.score
			player_score.put()
		self.delete()
		setScoreCache()

	def get_players(self):
		return Players.get(self.players)

	def get_players_num(self):
		return len(self.players)

class PlayerScore(db.Model):
	raid = db.ReferenceProperty(Raid)
	player = db.ReferenceProperty(Players)
	earn = db.IntegerProperty(default=0)
	adjust = db.IntegerProperty(default=0)
	reward = db.IntegerProperty(default=0)
	punishment = db.IntegerProperty(default=0)
	cost = db.IntegerProperty(default=0)
	attend = db.IntegerProperty(default=0)

	def attend_rate(self):
		try:
			event_num = EventData.all().count()
			return int(float(self.attend)/float(event_num)*100)
		except:
			event_num = 100
			return event_num

	def current_score(self):
		return self.earn+self.adjust+self.reward-self.punishment-self.cost


def createAllCache():
	players = Players.all()
	events = EventData.all()
	gears = GearData.all()
	action = ActionInEvent.all()
	punishment = PunishmentInEvent.all()
	reward = RewardInEvent.all()
	playerscore = PlayerScore.all()

	memcache.set_multi({'cache_players':players,
					   'cache_events':events,
					   'cache_gears':gears,
					   'cache_action':action,
					   'cache_punishment':punishment,
					   'cache_reward':reward,
					   'cache_score':playerscore})

def setScoreCache():
	memcache.set('cache_score',PlayerScore.all())